package com.cool.modules.finance.service.account.impl;

import cn.hutool.json.JSONObject;
import com.cool.core.base.BaseServiceImpl;
import com.cool.core.exception.CoolException;
import com.cool.modules.base.entity.sys.table.BaseSysUserEntityTableDef;
import com.cool.modules.base.service.sys.BaseSysUserService;
import com.cool.modules.finance.constant.InOrOutType;
import com.cool.modules.finance.constant.TransferType;
import com.cool.modules.finance.dto.FinanceTransferAccountRes;
import com.cool.modules.finance.dto.FinanceTransferAccountVo;
import com.cool.modules.finance.dto.TransferListReq;
import com.cool.modules.finance.entity.account.FinanceTransferAccountEntity;
import com.cool.modules.finance.entity.account.table.FinanceAccountEntityTableDef;
import com.cool.modules.finance.entity.account.table.FinanceTransferAccountEntityTableDef;
import com.cool.modules.finance.entity.coin.table.FinanceCoinEntityTableDef;
import com.cool.modules.finance.mapper.account.FinanceTransferAccountMapper;
import com.cool.modules.finance.service.account.FinanceTransferAccountService;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
@RequiredArgsConstructor
public class FinanceTransferAccountServiceImpl extends BaseServiceImpl<FinanceTransferAccountMapper,FinanceTransferAccountEntity> implements FinanceTransferAccountService {

    final BaseSysUserService baseSysUserService;

    @Override
    public void saveRecord(FinanceTransferAccountVo financeTransferAccountVo) {
        FinanceTransferAccountEntity transferAccount = new FinanceTransferAccountEntity();
        transferAccount.setOutAccount(financeTransferAccountVo.getOutAccountId());
        transferAccount.setInAccount(financeTransferAccountVo.getInAccountId());
        transferAccount.setTransferType(financeTransferAccountVo.getTransferType());
        transferAccount.setRepayMoney(financeTransferAccountVo.getTransferMoney());
        transferAccount.setRepayReason(financeTransferAccountVo.getRemark());
        transferAccount.setOutAccountUserId(financeTransferAccountVo.getOutAccountUserId());
        transferAccount.setInAccountUserId(financeTransferAccountVo.getInAccountUserId());
        transferAccount.setTransferTime(financeTransferAccountVo.getTransferTime()==null?new Date():financeTransferAccountVo.getTransferTime());
        save(transferAccount);
    }

    @Override
    public FinanceTransferAccountRes getTransferAccountList(JSONObject requestParams) {
        TransferListReq req = requestParams.toBean(TransferListReq.class);
        if (null!=req.getStartIndex()&&null!=req.getEndIndex()&& null!=req.getAccountId()){
            QueryWrapper query = new QueryWrapper();

            FinanceAccountEntityTableDef ACCOUNT1 = FinanceAccountEntityTableDef.FINANCE_ACCOUNT_ENTITY.as("a1");
            FinanceAccountEntityTableDef ACCOUNT2 = FinanceAccountEntityTableDef.FINANCE_ACCOUNT_ENTITY.as("a2");
            FinanceTransferAccountEntityTableDef TRANSFER = FinanceTransferAccountEntityTableDef.FINANCE_TRANSFER_ACCOUNT_ENTITY.as("t");
            FinanceCoinEntityTableDef COIN = FinanceCoinEntityTableDef.FINANCE_COIN_ENTITY.as("coin");
            BaseSysUserEntityTableDef INUSER = BaseSysUserEntityTableDef.BASE_SYS_USER_ENTITY.as("iu");
            BaseSysUserEntityTableDef OUTUSER = BaseSysUserEntityTableDef.BASE_SYS_USER_ENTITY.as("ou");

            query.select(TRANSFER.ALL_COLUMNS,
                            ACCOUNT1.ACCOUNT_NAME.as(FinanceTransferAccountEntity::getInAccountName),
                            ACCOUNT2.ACCOUNT_NAME.as(FinanceTransferAccountEntity::getOutAccountName),
                            COIN.COIN_NAME.as(FinanceTransferAccountEntity::getInAccountCoinName),
                            COIN.SYMBOL.as(FinanceTransferAccountEntity::getInAccountCoinSymbol),
                            INUSER.NAME.as(FinanceTransferAccountEntity::getInAccountUserName),
                            OUTUSER.NAME.as(FinanceTransferAccountEntity::getOutAccountUserName)
                    ).from(TRANSFER).
                    leftJoin(ACCOUNT1).
                    on(ACCOUNT1.ID.eq(TRANSFER.IN_ACCOUNT)).
                    leftJoin(ACCOUNT2).
                    on(ACCOUNT2.ID.eq(TRANSFER.OUT_ACCOUNT)).
                    leftJoin(INUSER).
                    on(INUSER.ID.eq(TRANSFER.IN_ACCOUNT_USER_ID)).
                    leftJoin(OUTUSER).
                    on(OUTUSER.ID.eq(TRANSFER.OUT_ACCOUNT_USER_ID)).
                    leftJoin(COIN).on(COIN.ID.eq(ACCOUNT1.COIN_ID)).
                    where(FinanceTransferAccountEntityTableDef.FINANCE_TRANSFER_ACCOUNT_ENTITY.IN_ACCOUNT.eq(req.getAccountId()).
                            or(FinanceTransferAccountEntityTableDef.FINANCE_TRANSFER_ACCOUNT_ENTITY.OUT_ACCOUNT.eq(req.getAccountId()))).
                    and(FinanceTransferAccountEntityTableDef.FINANCE_TRANSFER_ACCOUNT_ENTITY.TRANSFER_TYPE.in(req.getTransferType()).when(null!=req.getTransferType())).
                    and(FinanceTransferAccountEntityTableDef.FINANCE_TRANSFER_ACCOUNT_ENTITY.IN_ACCOUNT.eq(req.getAccountId()).when(null!=req.getInOrOut()&&req.getInOrOut().equals(InOrOutType.IN.getType()))).
                    and(FinanceTransferAccountEntityTableDef.FINANCE_TRANSFER_ACCOUNT_ENTITY.OUT_ACCOUNT.eq(req.getAccountId()).when(null!=req.getInOrOut()&&req.getInOrOut().equals(InOrOutType.OUT.getType()))).
                    and(FinanceTransferAccountEntityTableDef.FINANCE_TRANSFER_ACCOUNT_ENTITY.IS_DEL.eq(false));
            long count = count(query);
            query.limit(req.getStartIndex(), req.getEndIndex()).orderBy(FinanceTransferAccountEntity::getTransferTime,false);
            List<FinanceTransferAccountEntity> list = list(query);
            list.forEach(transfer->{
                if (transfer.getOutAccount().equals(req.getAccountId())){
                    transfer.setInOrOut(InOrOutType.OUT);
                    transfer.setInOrOutText(InOrOutType.OUT.getDesc());
                }
                if (transfer.getInAccount().equals(req.getAccountId())){
                    transfer.setInOrOut(InOrOutType.IN);
                    transfer.setInOrOutText(InOrOutType.IN.getDesc());
                }
                transfer.setTransferTypeText(TransferType.getByType(transfer.getTransferType()));
            });
            if (null!=req.getInOrOut()){
                list = list.stream().filter(transfer->transfer.getInOrOut().equals(InOrOutType.getEnumByType(req.getInOrOut()))).toList();
            }
            return new FinanceTransferAccountRes(count,list);
        }
        throw new CoolException("查询范围不能为空");
    }
}
